package com.example.dmservice.exceloutput.service;

import com.google.gson.Gson;
import okhttp3.*;
import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.http.RequestEntity;

import javax.net.ssl.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class HttpClient {

    // 请求的地址
    private String url;
    // 请求的参数
    private Map<String, String> param;
    private int statusCode;
    // 请求后，获取到的响应内容
    private String content;
    private String xmlParam;
    private boolean isHttps;

    public boolean isHttps() {
        return isHttps;
    }

    public void setHttps(boolean isHttps) {
        this.isHttps = isHttps;
    }

    public String getXmlParam() {
        return xmlParam;
    }

    public void setXmlParam(String xmlParam) {
        this.xmlParam = xmlParam;
    }

    public HttpClient(String url, Map<String, String> param) {
        this.url = url;
        this.param = param;
    }
    public HttpClient() {
    }
    public HttpClient(String url) {
        this.url = url;
    }

    public void setParameter(Map<String, String> map) {
        param = map;
    }

    public void addParameter(String key, String value) {
        if (param == null)
            param = new HashMap<String, String>();
        param.put(key, value);
    }

    /**
     * 发送post请求
     * @throws ClientProtocolException
     * @throws IOException
     */
    public void post() throws ClientProtocolException, IOException {
        HttpPost http = new HttpPost(url);
        setEntity(http);
        execute(http);
    }

    /**
     * 发送put请求
     * @throws ClientProtocolException
     * @throws IOException
     */
    public void put() throws ClientProtocolException, IOException {
        HttpPut http = new HttpPut(url);
        setEntity(http);
        execute(http);
    }

    /**
     * 发送get请求
     * @throws ClientProtocolException
     * @throws IOException
     */
    public void get() throws ClientProtocolException, IOException {
        if (param != null) {
            StringBuilder url = new StringBuilder(this.url);
            boolean isFirst = true;
            for (String key : param.keySet()) {
                if (isFirst)
                    url.append("?");
                else
                    url.append("&");
                url.append(key).append("=").append(param.get(key));
            }
            this.url = url.toString();
        }
        HttpGet http = new HttpGet(url);
        execute(http);
    }

    /**
     * set http post,put param
     */
    private void setEntity(HttpEntityEnclosingRequestBase http) {
        if (param != null) {
            List<NameValuePair> nvps = new LinkedList<NameValuePair>();
            for (String key : param.keySet())
                nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数
            http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数
        }
        if (xmlParam != null) {
            http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));
        }
    }

    /**
     * 真正发送请求的方法
     * @param http
     * @throws ClientProtocolException
     * @throws IOException
     */
    private void execute(HttpUriRequest http) throws ClientProtocolException,
            IOException {
        CloseableHttpClient httpClient = null;
        try {
            if (isHttps) {
                SSLContext sslContext = new SSLContextBuilder()
                        .loadTrustMaterial(null, new TrustStrategy() {
                            // 信任所有
                            public boolean isTrusted(X509Certificate[] chain,
                                                     String authType)
                                    throws CertificateException {
                                return true;
                            }
                        }).build();
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                        sslContext);
                httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
                        .build();
            } else {
                httpClient = HttpClients.createDefault();
            }
            CloseableHttpResponse response = httpClient.execute(http);
            try {
                if (response != null) {
                    if (response.getStatusLine() != null)
                        statusCode = response.getStatusLine().getStatusCode();
                    HttpEntity entity = response.getEntity();
                    // 响应内容
                    content = EntityUtils.toString(entity, Consts.UTF_8);
                }
            } finally {
                response.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            httpClient.close();
        }
    }

    public int getStatusCode() {
        return statusCode;
    }

    public String getContent() throws ParseException, IOException {
        return content;
    }

//    public static Map<String, Object> sendPost(String url, String param) {
//        PrintWriter out = null;
//        BufferedReader in = null;
//        StringBuilder result = new StringBuilder();
//        try {
//            URL realUrl = new URL(url);
//            URLConnection connection = realUrl.openConnection();
//            connection.setRequestProperty("accept", "*/*");
//            connection.setRequestProperty("connection", "Keep-Alive");
//            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
//            connection.setRequestProperty("Accept-Charset", "utf-8");
//            connection.setRequestProperty("contentType", "utf-8");
//            connection.setDoOutput(true);
//            connection.setDoInput(true);
//            out = new PrintWriter(connection.getOutputStream());
//            out.print(param);
//            out.flush();
//            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));
//            String line;
//            while ((line = in.readLine()) != null) {
//                result.append(line);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            try {
//                if (out != null) {
//                    out.close();
//                }
//                if (in != null) {
//                    in.close();
//                }
//            } catch (IOException ex) {
//                ex.printStackTrace();
//            }
//        }
//        String result1 = result.toString();
//        Map<String, Object> map = new Gson().fromJson(result1, Map.class);
//        return map;
//    }
public static Map<String, Object> sendGet(String reqUrl) {
    try {
        // 创建一个信任所有证书的 TrustManager
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[0];
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
        };

        // 创建 SSL 上下文，使用信任所有证书的 TrustManager
        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

        // 设置 OkHttpClient 使用我们创建的 SSL 上下文
        OkHttpClient client = new OkHttpClient.Builder()
                .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0])
                .hostnameVerifier((hostname, session) -> true)
                .build();

        Request request = new Request.Builder()
                .url(reqUrl)
                .method("GET", null)
                .addHeader("Accept", "application/json")
                .build();

        // 发送请求
        Response response = client.newCall(request).execute();
        Map<String, Object> map = new Gson().fromJson(response.body().string(), Map.class);

        return map;
    } catch (Exception e) {
        throw new RuntimeException("HTTP GET同步请求失败 URL:" + reqUrl, e);
    }
}
    public static Map<String, Object> sendPost(String reqUrl, String json) {
        try {
            // 创建一个信任所有证书的 TrustManager
            TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        public X509Certificate[] getAcceptedIssuers() {
                            return new X509Certificate[0];
                        }

                        public void checkClientTrusted(X509Certificate[] certs, String authType) {
                        }

                        public void checkServerTrusted(X509Certificate[] certs, String authType) {
                        }
                    }
            };

            // 创建 SSL 上下文，使用信任所有证书的 TrustManager
            SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

            // 设置 OkHttpClient 使用我们创建的 SSL 上下文
            OkHttpClient client = new OkHttpClient.Builder()
                    .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0])
                    .hostnameVerifier((hostname, session) -> true)
                    .build();

            MediaType mediaType = MediaType.parse("application/json");
            RequestBody body = RequestBody.create(mediaType, json);
            Request request = new Request.Builder()
                    .url(reqUrl)
                    .method("POST", body)
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Accept", "application/json")
                    .build();

            // 发送请求
            Response response = client.newCall(request).execute();
            Map<String, Object> map = new Gson().fromJson(response.body().string(), Map.class);

            return map;
        } catch (Exception e) {
            throw new RuntimeException("HTTP POST同步请求失败 URL:" + reqUrl, e);
        }
    }

    /**
     * httpClient-Post请求
     * @param url 请求地址
     * @param params post参数
     * @return
     * @throws Exception
     */
//    public static Map<String, Object> httpClientPost(String url, String params) throws Exception {
//        org.apache.commons.httpclient.HttpClient client = new org.apache.commons.httpclient.HttpClient();
//        client.getParams().setContentCharset("UTF-8");
//        PostMethod httpPost = new PostMethod(url);
//        try {
//            RequestEntity requestEntity = new ByteArrayRequestEntity(params.getBytes("utf-8"));
//            httpPost.setRequestEntity(requestEntity);
//            client.executeMethod(httpPost);
//            String response = httpPost.getResponseBodyAsString();
//            Map<String, Object> map = new Gson().fromJson(response, Map.class);
//            return map;
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        } finally {
//            httpPost.releaseConnection();
//        }
//    }

    /**
     * httpClient-Get请求
     * @param url 请求地址
     * @return
     * @throws Exception
     */
//    public static Map<String, Object> httpClientGet(String url) throws Exception {
//        org.apache.commons.httpclient.HttpClient client = new org.apache.commons.httpclient.HttpClient();
//        client.getParams().setContentCharset("UTF-8");
//        GetMethod httpGet = new GetMethod(url);
//        try {
//            client.executeMethod(httpGet);
//            String response = httpGet.getResponseBodyAsString();
//            Map<String, Object> map = new Gson().fromJson(response, Map.class);
//            return map;
//        } catch (Exception e) {
//            throw e;
//        } finally {
//            httpGet.releaseConnection();
//        }
//    }
}
